package com.zx.crowdfunding.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zx.crowdfunding.constant.CrowdFundingConstant;
import com.zx.crowdfunding.entity.Admin;
import com.zx.crowdfunding.entity.AdminExample;
import com.zx.crowdfunding.entity.AdminExample.Criteria;
import com.zx.crowdfunding.exception.LoginAcctAlreadyInUseException;
import com.zx.crowdfunding.exception.LoginFailedException;
import com.zx.crowdfunding.mapper.AdminMapper;
import com.zx.crowdfunding.service.api.AdminService;
import com.zx.crowdfunding.util.CrowdFundingUtil;

/**
 * 管理员	- Service接口实现类
 * @author 郑雪
 * @date 2021-12-07
 */
@Service
public class AdminServiceImpl implements AdminService {
	
	private Logger logger = LoggerFactory.getLogger(AdminServiceImpl.class);
	
	/**
	 * 管理员Mapper接口
	 */
	@Autowired
	private AdminMapper adminMapper;
	
	/**
	 * SpringSecurity的密码编码器
	 */
	@Autowired
	private PasswordEncoder passwordEncoder;

	@Override
	public void saveAdmin(Admin admin) {
		
		// 1.密码加密
		String userPswd = admin.getUserPswd();
		//userPswd = CrowdFundingUtil.md5(userPswd);
		userPswd = passwordEncoder.encode(userPswd);
		admin.setUserPswd(userPswd);
		
		
		// 2.生成创建时间
		Date date = new Date();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String createTime = simpleDateFormat.format(date);
		admin.setCreateTime(createTime);
		
		// 3.执行保存
		try {
			adminMapper.insert(admin);
		} catch (Exception e) {
			// e.printStackTrace();
			
			// 打印
			logger.info("异常全类名："+e.getClass().getName());
			
			// 如果是违反唯一约束的异常
			if(e instanceof DuplicateKeyException){
				throw new LoginAcctAlreadyInUseException(CrowdFundingConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE, "admin-add");
			}
		}
	}
	
	@Override
	public Admin getAdminByLoginAcct(String loginAcct) {
		
		// 1.根据登录账号查询Admin对象
		// ①创建AdminExample对象
		AdminExample adminExample = new AdminExample();
		
		// ②创建Criteria对象
		Criteria criteria = adminExample.createCriteria();
		
		// ③在Criteria对象中封装查询条件
		criteria.andLoginAcctEqualTo(loginAcct);
		
		// ④调用AdminMapper的方法执行查询
		List<Admin> list = adminMapper.selectByExample(adminExample);
		
		// 2.判断Admin对象是否为null
		if(list == null || list.size() == 0){
			throw new LoginFailedException(CrowdFundingConstant.MESSAGE_LOGIN_FAILED);
		}
		
		if(list.size() > 1){
			throw new RuntimeException(CrowdFundingConstant.MESSAGE_SYSTEM_ERROR_LOGIN_NOT_UNIQUE);
		}
		
		// 3.如果Admin对象为null则抛出异常
		Admin admin = list.get(0);
		if(admin == null){
			throw new LoginFailedException(CrowdFundingConstant.MESSAGE_LOGIN_FAILED);
		}
		
		// 4.如果Admin对象不为null则返回Admin对象
		return admin;
	}

	@Override
	public Admin getAdminByLoginAcct(String loginAcct, String userPswd) {
		
		// 1.根据登录账号查询Admin对象
		// ①创建AdminExample对象
		AdminExample adminExample = new AdminExample();
		
		// ②创建Criteria对象
		Criteria criteria = adminExample.createCriteria();
		
		// ③在Criteria对象中封装查询条件
		criteria.andLoginAcctEqualTo(loginAcct);
		
		// ④调用AdminMapper的方法执行查询
		List<Admin> list = adminMapper.selectByExample(adminExample);
		
		// 2.判断Admin对象是否为null
		if(list == null || list.size() == 0){
			throw new LoginFailedException(CrowdFundingConstant.MESSAGE_LOGIN_FAILED);
		}
		
		if(list.size() > 1){
			throw new RuntimeException(CrowdFundingConstant.MESSAGE_SYSTEM_ERROR_LOGIN_NOT_UNIQUE);
		}
		
		// 3.如果Admin对象为null则抛出异常
		Admin admin = list.get(0);
		if(admin == null){
			throw new LoginFailedException(CrowdFundingConstant.MESSAGE_LOGIN_FAILED);
		}
		
		// 4.如果Admin对象不为null则将数据库密码从Admin对象中取出
		String userPswdDB = admin.getUserPswd();
		
		// 5.将表单提交的明文密码进行MD5加密
		String userPswdForm = CrowdFundingUtil.md5(userPswd);
		
		// 6.对密码进行比较
		if(!Objects.equals(userPswdDB, userPswdForm)){
			// 7.如果比较结果是不一致，则抛出异常
			throw new LoginFailedException(CrowdFundingConstant.MESSAGE_LOGIN_FAILED);
		}
		
		// 8.如果一致则返回Admin对象
		return admin;
	}

	@Override
	public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {
		
		// 1.调用PageHelper的静态方法开启分页功能
		PageHelper.startPage(pageNum, pageSize);
		
		// 2.执行查询
		List<Admin> list = adminMapper.selectByKeyword(keyword);
		
		// 3.封装到PageInfo对象中
		return new PageInfo<Admin>(list);
	}

	@Override
	public void removeAdmin(Integer id) {
		adminMapper.deleteByPrimaryKey(id);
	}

	@Override
	public Admin getAdminById(Integer id) {
		return adminMapper.selectByPrimaryKey(id);
	}

	@Override
	public void editAdmin(Admin admin) {
		try {
			adminMapper.updateByPrimaryKeySelective(admin);
		} catch (Exception e) {
			//e.printStackTrace();
			
			// 打印
			logger.info("异常全类名："+e.getClass().getName());
			
			// 如果是违反唯一约束的异常
			if(e instanceof DuplicateKeyException){
				throw new LoginAcctAlreadyInUseException(CrowdFundingConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE, "system-error");
			}
		}
	}

	@Override
	public void saveAdminRoleRelationship(Integer adminId,
			List<Integer> roleIdList) {
		
		// 根据adminId删除旧的关联关系数据
		adminMapper.deleteAdminRoleRelationship(adminId);
		
		// 添加关联关系数据
		if(roleIdList != null && roleIdList.size()>0){
			adminMapper.insertAdminRoleRelationship(adminId, roleIdList);
		}
	}

}
